package com.sgcc.dlsc.monitorredis.service.impl;

import com.sgcc.dlsc.monitorredis.config.TimeTask;
import com.sgcc.dlsc.monitorredis.dao.MonitorRedisMapper;
import com.sgcc.dlsc.monitorredis.model.po.ClusterConfig;
import com.sgcc.dlsc.monitorredis.model.bo.Group;
import com.sgcc.dlsc.monitorredis.model.bo.Monitor;
import com.sgcc.dlsc.monitorredis.model.po.Host;
import com.sgcc.dlsc.monitorredis.service.GetInfoService;
import com.sgcc.dlsc.monitorredis.util.CommandProcess;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.util.*;

/**
 * @Author: 李孟帅
 * @CreateTime: 2019-08-28 11:13
 * @Description: ${Description}
 */
@Service
public class GetInfoServiceImpl implements GetInfoService {
    private JedisConnectionFactory redisConnectionFactory;
    @Resource
    private MonitorRedisMapper monitorRedisMapper;
    @Resource
    private Monitor monitor;
    @Resource
    private TimeTask timeTask;

    /**
     * @Author 李孟帅
     * @Description 添加redis节点并返回其状态
     * @Date 9:54 2019/9/26
     **/
    @Override
    public String addNode(Host host) {
        String ip = host.getIp();
        String username = host.getUsername();
        String password = host.getPassword();
        List<String> command = new ArrayList<String>();
        command.add("sh");
        command.add("/etc/ansible/redis/getinfo.sh");
        command.add(ip);
        command.add(username);
        command.add(password);
        try {
            String info = CommandProcess.syncExec(command);
            if ("节点已存在".equals(info) || "节点不存在或连不通".equals(info)) {
                return info;
            } else {
                String[] splits = info.split("\\\\n|:| ");
                host.setTotalMemory(splits[1]);
                host.setUsedMemory(splits[3]);
                host.setTotalDisk(splits[5]);
                host.setUsedDisk(splits[7]);
                host.setStatus("online");
                System.out.println(host);
                monitorRedisMapper.addNode(host);
                return "添加节点成功";
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "添加失败";
        }
    }

    /**
     * @Author 李孟帅
     * @Description 获取节点状态
     * @Date 9:56 2019/9/26
     **/
    @Override
    public List<Host> selectNodes() {

        String isOnline = null;
        try {
            isOnline = CommandProcess.syncExec("sh /etc/ansible/redis/isOnline.sh");
            String[] split = isOnline.split("\n");
            Host host = new Host();
            for (int i = 0; i < split.length; i++) {
                if (split[i].contains("online")) {
                    String[] split1 = split[i].split("=");
                    String ip = split1[0];
                    String info = split1[1];
                    String[] split2 = info.split("\\\\n|:| ");
                    host.setIp(ip);
                    host.setTotalMemory(split2[1]);
                    host.setUsedMemory(split2[3]);
                    host.setTotalDisk(split2[5]);
                    host.setUsedDisk(split2[7]);
                    host.setStatus("online");
                    System.out.println(host);
                    monitorRedisMapper.update(host);
                } else {
                    monitorRedisMapper.updateSatus(split[i].split("=")[0]);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return monitorRedisMapper.selectNodes();
    }

    /**
     * @Author 李孟帅
     * @Description 创建redis集群
     * @Date 16:16 2019/10/10
     **/
    @Override
    public String createRedisCluster(ClusterConfig clusterConfig) throws Exception {
        String clusterName = clusterConfig.getClusterName();
        List<String> nodes = clusterConfig.getNodes();
        String replicationNum = clusterConfig.getReplicationNum();
        File file = new File("/etc/ansible/redis/clusterConfig");
        BufferedWriter bw = null;
        List<String> command = new ArrayList<String>();
        command.add("sh");
        command.add("/etc/ansible/redis/createRedisCluster.sh");
        command.add(clusterName);
        try {
            bw = new BufferedWriter(new FileWriter(file, true));
            bw.write("<" + clusterName + ">\n");
            bw.write("[nodes]\n");
            for (String node : nodes) {
                bw.write(node);
                bw.write("\n");
            }
            bw.write("[config]\n");
            bw.write("replication:");
            bw.write(replicationNum);
            bw.write("\n");
            bw.write("</" + clusterName + ">\n\n");
            bw.flush();

            CommandProcess.syncExec(command);
            redisConnectionFactory = getRedisConnectionFactory(clusterName);
            monitor.getClusters().put(clusterName, redisConnectionFactory);
            monitor.getClusterNameList().add(clusterName);
            timeTask.startTask(clusterName);
            System.out.println("集群创建成功");

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
            CommandProcess.syncExec("sh /etc/ansible/redis/deleteCluster.sh "+clusterName);
            return "创建集群失败";
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "创建集群成功";
    }

    /**
     * @Author 李孟帅
     * @Description 从内存中获取集群列表
     * @Date 16:16 2019/10/10
     **/
    @Override
    public Map<String, List<Group>> getClusterList() {

        return TimeTask.clusterMap;

    }

    //将集群连接池存入内存中
    private JedisConnectionFactory getRedisConnectionFactory(String clusterName) {
        try {
            String result = CommandProcess.syncExec("sh /etc/ansible/redis/getNode.sh " + clusterName);
            String[] split = result.split(" ");
            List<String> nodes = Arrays.asList(split);
            redisConnectionFactory = new JedisConnectionFactory(new RedisClusterConfiguration(nodes));
            redisConnectionFactory.afterPropertiesSet();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return redisConnectionFactory;
    }



}
